﻿namespace DesignModeConsole.行为型.观察者模式.EventBusSample;

/// <summary>
/// 事件总线接口
/// </summary>
public interface IEventBus
{
    #region 接口注册

    /// <summary>
    /// 注册
    /// </summary>
    /// <param name="handlerType">处理程序</param>
    /// <typeparam name="TEventData">参数类型</typeparam>
    void Register<TEventData>(Type handlerType) where TEventData : EventData;

    /// <summary>
    /// 注册
    /// </summary>
    /// <param name="eventType">参数类型</param>
    /// <param name="handlerType">处理程序</param>
    void Register(Type eventType, Type handlerType);

    /// <summary>
    /// 注册
    /// </summary>
    /// <param name="eventType">时间参数类型名</param>
    /// <param name="handlerType">执行程序类型</param>
    void Register(string eventType, Type handlerType);

    #endregion

    #region 接口取消注册

    /// <summary>
    /// 取消注册
    /// </summary>
    /// <param name="handlerType">处理程序</param>
    /// <typeparam name="TEventData">参数类型</typeparam>
    void Unregister<TEventData>(Type handler) where TEventData : EventData;

    /// <summary>
    /// 取消注册
    /// </summary>
    /// <param name="eventType">参数类型</param>
    /// <param name="handlerType">处理程序</param>
    void Unregister(Type eventType, Type handlerType);

    /// <summary>
    /// 取消注册
    /// </summary>
    /// <param name="eventType">时间参数类型名</param>
    /// <param name="handlerType">执行程序类型</param>
    void Unregister(string eventType, Type handlerType);

    #endregion

    /// <summary>
    /// 执行
    /// </summary>
    /// <param name="pubKey">参数类型Name</param>
    /// <param name="eventData">参数数据</param>
    void Trigger(string pubKey, EventData eventData);

    /// <summary>
    /// 异步执行
    /// </summary>
    /// <param name="pubKey">参数类型Name</param>
    /// <param name="eventData">参数数据</param>
    Task TriggerAsync(string pubKey, EventData eventData);

    /// <summary>
    /// 异步执行
    /// </summary>
    /// <param name="eventData">事件参数</param>
    /// <typeparam name="TEventData">事件参数类型</typeparam>
    /// <returns></returns>
    Task TriggerAsync<TEventData>(TEventData eventData) where TEventData : EventData;

    /// <summary>
    /// 执行
    /// </summary>
    /// <param name="eventData">事件参数</param>
    /// <typeparam name="TEventData">事件参数类型</typeparam>
    void Trigger<TEventData>(TEventData eventData) where TEventData : EventData;
}

/// <summary>
/// 事件总线方法参数约束
/// </summary>
public class EventData
{
    protected EventData()
    {
        Id = Guid.NewGuid().ToString();
        EventTime = DateTime.Now;
    }

    /// <summary>
    /// 事件ID
    /// </summary>
    public string Id { get; }

    /// <summary>
    /// 执行时间
    /// </summary>
    private DateTime EventTime { get; }
}